*&---------------------------------------------------------------------*
*& Report ZEX_LISTING_216                                              *
*&---------------------------------------------------------------------*
*& Created By: James Wood (james.wood@bowdarkconsulting.com)           *
*& Created On: 12/12/2008                                              *
*& Purpose:    This program demonstrates the revised Point API         *
*&             described in Listing 2.16 and Listing 2.17.             *
*&---------------------------------------------------------------------*
REPORT zex_listing_216.

*----------------------------------------------------------------------*
*       CLASS lcl_point DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_point DEFINITION.

  PUBLIC SECTION.
    CONSTANTS: co_quadrant_1 TYPE i VALUE 1,
               co_quadrant_2 TYPE i VALUE 2,
               co_quadrant_3 TYPE i VALUE 3,
               co_quadrant_4 TYPE i VALUE 4.

    CLASS-DATA: next_point_no TYPE i. "Next Point Number

    DATA: point_no TYPE i,            "Point Number
          x        TYPE i,            "X-Coordinate
          y        TYPE i.            "Y-Coordinate

    METHODS:
      constructor,
      get_point_number RETURNING value(re_number)
                            TYPE i,
      get_quadrant     RETURNING value(re_quadrant)
                            TYPE i.

    CLASS-METHODS:
      get_distance IMPORTING im_point1
                    TYPE REF TO lcl_point
                             im_point2
                    TYPE REF TO lcl_point
                   RETURNING value(re_distance)
                        TYPE f.

ENDCLASS.                    "lcl_point DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_point IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_point IMPLEMENTATION.

  METHOD constructor.
    next_point_no = next_point_no + 1.
    point_no = next_point_no.
  ENDMETHOD.

  METHOD get_point_number.
    re_number = point_no.
  ENDMETHOD.

  METHOD get_quadrant.
    IF x > 0.
      IF y > 0.
        re_quadrant = CO_QUADRANT_1.
      ELSE.
        re_quadrant = CO_QUADRANT_4.
      ENDIF.
    ELSE.
      IF y > 0.
        re_quadrant = CO_QUADRANT_2.
      ELSE.
        re_quadrant = CO_QUADRANT_3.
      ENDIF.
    ENDIF.
  ENDMETHOD.

  METHOD get_distance.
*   Method-Local Data Declarations:
    DATA: lv_dx TYPE i, "Diff. X
          lv_dy TYPE i. "Diff. Y

*   Calculate the distance between the two points:
    lv_dx = im_point2->x - im_point1->x.
    lv_dy = im_point2->y - im_point1->y.

    re_distance =
      SQRT( ( lv_dx * lv_dx ) + ( lv_dy * lv_dy ) ).
  ENDMETHOD.

ENDCLASS.                    "lcl_point IMPLEMENTATION

*&---------------------------------------------------------------------*
*& START-OF-SELECTION Event                                            *
*&---------------------------------------------------------------------*
START-OF-SELECTION.
  PERFORM test_point_class.

*&---------------------------------------------------------------------*
*&      Form  test_point_class
*&---------------------------------------------------------------------*
FORM test_point_class.

* Local Data Declarations:
  DATA: lr_point_a TYPE REF TO lcl_point,
        lr_point_b TYPE REF TO lcl_point,
        lr_point_c TYPE REF TO lcl_point,
        lr_point_d TYPE REF TO lcl_point,
        lv_point_number TYPE numc1,
        lv_quadrant TYPE numc1,
        lv_distance TYPE f.

* Create some sample point objects:
  CREATE OBJECT lr_point_a.
  lr_point_a->x = 2.
  lr_point_a->y = 3.

  CREATE OBJECT lr_point_b.
  lr_point_b->x = 2.
  lr_point_b->y = -1.

  CREATE OBJECT lr_point_c.
  lr_point_c->x = -3.
  lr_point_c->y = -4.

  CREATE OBJECT lr_point_d.
  lr_point_d->x = -5.
  lr_point_d->y = 1.

* Determine the point number & quadrant of point C:
  lv_point_number = lr_point_c->get_point_number( ).
  lv_quadrant = lr_point_c->get_quadrant( ).

  WRITE: / 'Point C has Point #', lv_point_number,
           'and resides in quadrant', lv_quadrant.

* Calculate the distance between points C and D:
  lv_distance =
    lcl_point=>get_distance( im_point1 = lr_point_c
                             im_point2 = lr_point_d ).

  WRITE: / 'Distance between point C and point D is: ', lv_distance.

ENDFORM.                    "test_point_class